package icu.wdtt.service.Impl;

import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.StpUtil;
import icu.wdtt.exception.FilesException;
import icu.wdtt.mapper.FilesMapper;
import icu.wdtt.mapper.UserMapper;
import icu.wdtt.model.Files;
import icu.wdtt.model.User;
import icu.wdtt.service.FilesService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Path;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Service
@Transactional
public class FilesServiceImpl implements FilesService {
    @Autowired
    private FilesMapper filesMapper;
    @Autowired
    private UserMapper userMapper;
    //文件存储地址
    private static String fileUrl = new File("src/main/resources/files/").getAbsolutePath();
    //静态初始块
    static{
        //创建目录对象
        File dir = new File(fileUrl);
        //判断文件目录是否存在
        if(!dir.exists()){
            //不存在则创建目录
            dir.mkdirs();
        }
    }
    @Override
    public Files get(int fid) {
        return filesMapper.getByUidAndFid(StpUtil.getLoginIdAsInt(),fid);
    }

    @Override
    public List<Files> getAll() {
        return filesMapper.getAll(StpUtil.getLoginIdAsInt());
    }

    @Override
    public Boolean add(MultipartFile[] files, int uid) throws Exception {
            for (MultipartFile file : files) {
                 //获取文件byte信息
                byte [] filesByte =  file.getBytes();
                //使用Spring自带的DigestUtils获取Md5值
                String md5 = DigestUtils.md5DigestAsHex(filesByte);
                //从数据库中查询是否存在该文件
                Files filesByMd5 = filesMapper.getFilesByMd5(md5);
                if(filesByMd5 != null){
                      //当有这个文件时
                    //判断该用户是不是保存过该文件
                    Integer flag = filesMapper.isFilesByUser(filesByMd5.getFid(), uid);
                    if(flag != null){
                        throw new FilesException("您已经保存过该文件!重复文件名为:"+filesByMd5.getFname());
                    }
                    //如果没有保存过 则保存
                    filesMapper.add(filesByMd5);
                    filesMapper.addFilesAndUser(filesByMd5.getFid(),uid);
                }else{
                    //当不存在该文件时
                    //设置保存地址
                    String saveUrl = fileUrl;
                    //设置文件的路径
                    saveUrl += "\\" + file.getOriginalFilename();
                    if(new File(saveUrl).exists()){
                        //当文件名重复时，使用UUID随机生成一个文件名覆盖
                        saveUrl += "." + UUID.randomUUID().toString();
                    }
                    //判断文件类型
                    String type = null;
                    //获取文件的MIME类型
                    String fileMIME = file.getContentType();

                    if(fileMIME.contains("image")){
                        //图片类型
                        type = "image";
                    }else if(fileMIME.contains("text")){
                        //文档类型
                        type = "text";
                    }else if(fileMIME.contains("audio")){
                        //音频类型
                        type = "audio";
                    }else if(fileMIME.contains("video")){
                        //视频类型
                        type = "video";
                    }else if(fileMIME.contains("application")){
                        //其他类型
                        type = "application";
                    }
                    //创建文件对象 准备将地址保存进数据库
                    Files files1 = new Files(-1,file.getOriginalFilename(),saveUrl,0,fileMIME,type,md5);
                    //保存文件
                    file.transferTo(new File(saveUrl));
                    filesMapper.add(files1);
                    filesMapper.addFilesAndUser(files1.getFid(),uid);
                }
            }
            return true;
    }

    @Override
    public Boolean del(int fid) {
        try {
            filesMapper.delFilesAndUser(fid);
            Files files = this.get(fid);
            if(files ==null){
                return false;
            }
            File file = new File(files.getFurl());
            //删除文件
            file.delete();
            filesMapper.del(fid);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }


    @Override
    public Files download(int fid, int uid) throws FilesException {

        Files files = filesMapper.getByFid(fid);
        Integer userFid = filesMapper.isFilesByUser(fid, uid);
        //判断是否属于该用户的文件
       if(userFid == null){
           //当不属于该用户的文件时，判断是否分享了
           if(files.getFopen() == 0){
               //也没有分享 直接报错
               throw new FilesException("您没有该文件的下载权限!");
           }
       }
        return files;
    }

    @Override
    public List<Files> getByFname(String fname, User user) {

        List<Files> filesList = filesMapper.getByRname(fname, user.getUid());
        return filesList;
    }

    @Override
    public List<Files> getByType(int uid,String ftype) {
        List<Files> mainFiles = this.getMainFiles(uid);
        List<Files> typeFiles = new ArrayList<>();
        mainFiles.forEach( s->{ if(s.getFtype().equals(ftype)) typeFiles.add(s);});
        return typeFiles;
    }

    @Override
    public List<Files> getMainFiles(int uid) {
        SaSession session = StpUtil.getSession();
        //第一个为key 第二为类型
        List<Files> filesList = session.getModel("filesList", List.class);
        if(filesList == null){
            filesList = filesMapper.getMainFiles(uid);
            session.set("filesList",filesList);
        }
        return filesList;
    }
    @Override
    public Boolean modifyFilesName(int fid , String fname) throws FilesException {

        Files files = filesMapper.getByFid(fid);
        if(files == null){
            throw new FilesException("文件不存在!");
        }

        Integer flag = filesMapper.isFilesByUser(fid, StpUtil.getLoginIdAsInt());
        if(flag != null){
            filesMapper.modifyFilesName(fid,fname);
            return true;
        }
        return false;
    }


}
